<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    .box1{width: 100px;height: 100px;background-color: red;position: absolute;left: 0;top:0;}
    .box2{width: 100px;height: 100px;background-color: green;position: absolute;left: 0;top:110px;}
    .line{width: 1px;height: 500px;background: black;position: absolute;left: 500px;top:0;}
  </style>
</head>
<body>
  <div class="box1"></div>
  <div class="box2"></div>
  <div class="line"></div>
</body>
<script>
  const box1 = document.querySelector(".box1");
  const box2 = document.querySelector(".box2");

  box1.onclick = function(){
    move(box1, {
      left: 400,
      top: 10
    });
  }


  // 任意属性运动

  function move(ele, data){
    if(ele.t) return;
    ele.t = setInterval(()=>{
      console.log(1);
      // 因为要操作多属性，属性和目标之间一一对应，符合对象的基本规范：键值对
      // 所以接收到要操作的属性和目标后，遍历解析对象，获取每个属性和对应目标
      for(let i in data){
        // 因为将来可能会传入各种属性，offset系列不一定能满足需求
        // 自己封装获取样式的功能，用来获取指定属性的当前值
        const now = parseInt(getStyle(ele, i));

        // 计算步长（缓冲的核心）
        let speed = (data[i] - now)/10;
        speed = speed < 0 ? Math.floor(speed) : Math.ceil(speed);

        // 修改当前元素的属性：当前值 + 步长
        ele.style[i] = now + speed + "px";
      }
    }, 30);
  }

  function getStyle(ele, attr){
    return ele.currentStyle ? ele.currentStyle[attr] : getComputedStyle(ele)[attr];
  }

</script>
</html>